const { prisma } = require('../config/prisma');

const getDayRange = (date = new Date()) => {
  const start = new Date(date);
  start.setHours(0, 0, 0, 0);
  const end = new Date(date);
  end.setHours(23, 59, 59, 999);
  return { start, end };
};

/**
 * 消息模型 - Prisma版本
 */
class MessagePrisma {
  constructor(data) {
    this.id = data.id;
    this.group_id = data.group_id;
    this.sender_id = data.sender_id;
    this.message_type = data.message_type;
    this.content = data.content;
    this.broadcast_tag = data.broadcast_tag;
    this.created_at = data.created_at;

    // 关联数据
    this.users = data.users;
    this.chat_groups = data.chat_groups;
  }

  /**
   * 发送消息
   * @param {Object} messageData 消息数据
   * @returns {Promise<MessagePrisma>}
   */
  static async create(messageData) {
    const { group_id, sender_id, message_type = 'text', content, broadcast_tag } = messageData;

    const message = await prisma.messages.create({
      data: {
        group_id: parseInt(group_id),
        sender_id: BigInt(sender_id),
        message_type,
        content,
        broadcast_tag: broadcast_tag || null
      }
    });

    return new MessagePrisma(message);
  }

  /**
   * 根据ID查找消息
   * @param {number} id 消息ID
   * @returns {Promise<MessagePrisma|null>}
   */
  static async findById(id) {
    const message = await prisma.messages.findUnique({
      where: { id: BigInt(id) }
    });

    return message ? new MessagePrisma(message) : null;
  }

  /**
   * 获取群组消息列表
   * @param {number} groupId 群组ID
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getGroupMessages(groupId, options = {}) {
    const { page = 1, pageSize = 50, lastMessageId } = options;
    const pageNum = parseInt(page) || 1;
    const pageSizeNum = parseInt(pageSize) || 50;
    const skip = (pageNum - 1) * pageSizeNum;

    const where = { group_id: parseInt(groupId) };

    // 如果提供了lastMessageId，则获取比它更新的消息
    if (lastMessageId && !isNaN(parseInt(lastMessageId))) {
      where.id = { gt: BigInt(lastMessageId) };
    }

    // 并行查询总数和列表数据
    const [total, messages] = await Promise.all([
      prisma.messages.count({ where }),
      prisma.messages.findMany({
        where,
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true
            }
          }
        },
        orderBy: { created_at: 'desc' },
        skip,
        take: pageSizeNum
      })
    ]);

    const messagesWithSender = messages.map(message => ({
      id: message.id.toString(),
      group_id: message.group_id.toString(),
      sender_id: message.sender_id.toString(),
      message_type: message.message_type,
      content: message.content,
      broadcast_tag: message.broadcast_tag,
      created_at: message.created_at,
      sender: {
        id: message.users?.id?.toString() || message.sender_id.toString(),
        nickname: message.users?.nickname || '未知用户',
        avatar_url: message.users?.avatar_url
      }
    }));

    return {
      data: messagesWithSender,
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total,
        totalPages: Math.ceil(total / pageSizeNum)
      }
    };
  }

  /**
   * 获取最新消息（用于轮询）
   * @param {number} groupId 群组ID
   * @param {number} lastMessageId 最后一条消息ID
   * @returns {Promise<Array>}
   */
  static async getNewMessages(groupId, lastMessageId = 0) {
    const messages = await prisma.messages.findMany({
      where: {
        group_id: parseInt(groupId),
        id: { gt: BigInt(lastMessageId) }
      },
      include: {
        users: {
          select: {
            id: true,
            nickname: true,
            avatar_url: true
          }
        }
      },
      orderBy: { created_at: 'asc' }
    });

    return messages.map(message => ({
      id: message.id.toString(),
      group_id: message.group_id.toString(),
      sender_id: message.sender_id.toString(),
      message_type: message.message_type,
      content: message.content,
      broadcast_tag: message.broadcast_tag,
      created_at: message.created_at,
      sender: {
        id: message.users?.id?.toString() || message.sender_id.toString(),
        nickname: message.users?.nickname || '未知用户',
        avatar_url: message.users?.avatar_url
      }
    }));
  }

  /**
   * 获取用户在所有群组的最新消息
   * @param {number} userId 用户ID
   * @param {number} limit 限制数量
   * @returns {Promise<Array>}
   */
  static async getUserLatestMessages(userId, limit = 20) {
    const messages = await prisma.messages.findMany({
      where: {
        chat_groups: {
          group_members: {
            some: {
              user_id: BigInt(userId)
            }
          }
        }
      },
      include: {
        users: {
          select: {
            id: true,
            nickname: true,
            avatar_url: true
          }
        },
        chat_groups: {
          select: {
            id: true,
            group_name: true
          }
        }
      },
      orderBy: { created_at: 'desc' },
      take: limit
    });

    return messages.map(message => ({
      id: message.id.toString(),
      group_id: message.group_id.toString(),
      sender_id: message.sender_id.toString(),
      message_type: message.message_type,
      content: message.content,
      created_at: message.created_at,
      sender: {
        nickname: message.users?.nickname || '未知用户',
        avatar_url: message.users?.avatar_url
      },
      group: {
        group_name: message.chat_groups?.group_name
      }
    }));
  }

  /**
   * 删除消息
   * @param {number} id 消息ID
   * @returns {Promise<boolean>}
   */
  static async delete(id) {
    await prisma.messages.delete({
      where: { id: BigInt(id) }
    });
    return true;
  }

  /**
   * 创建系统消息
   * @param {number} groupId 群组ID
   * @param {string} content 消息内容
   * @returns {Promise<MessagePrisma>}
   */
  static async createSystemMessage(groupId, content) {
    return await this.create({
      group_id: groupId,
      sender_id: 0, // 系统消息使用0作为发送者ID
      message_type: 'system',
      content: content
    });
  }

  /**
   * 获取群组消息统计
   * @param {number} groupId 群组ID
   * @returns {Promise<Object>}
   */
  static async getGroupMessageStats(groupId) {
    const [total, today] = await Promise.all([
      prisma.messages.count({ where: { group_id: parseInt(groupId) } }),
      prisma.messages.count({
        where: {
          group_id: parseInt(groupId),
          created_at: {
            gte: new Date(new Date().setHours(0, 0, 0, 0))
          }
        }
      })
    ]);

    return { total, today };
  }

  /**
   * 获取群组日活跃用户统计
   * @param {number} groupId 群组ID
   * @returns {Promise<Object>}
   */
  static async getGroupDailyActiveStats(groupId) {
    const today = new Date();
    const todayStart = new Date(today.setHours(0, 0, 0, 0));
    const todayEnd = new Date(today.setHours(23, 59, 59, 999));

    // 获取今天发送消息的用户数量（去重）
    const dailyActiveUsers = await prisma.messages.findMany({
      where: {
        group_id: parseInt(groupId),
        created_at: {
          gte: todayStart,
          lte: todayEnd
        }
      },
      select: {
        sender_id: true
      },
      distinct: ['sender_id']
    });

    return {
      dailyActiveUsers: dailyActiveUsers.length
    };
  }

  /**
   * 获取所有群组的汇总统计（全国总群用）
   * @returns {Promise<Object>}
   */
  static async getAllGroupsStats() {
    const today = new Date();
    const todayStart = new Date(today.setHours(0, 0, 0, 0));
    const todayEnd = new Date(today.setHours(23, 59, 59, 999));

    // 获取系统总用户数（不重复统计）
    const totalUsers = await prisma.users.count();

    // 获取今天在所有群聊中发送消息的用户数量（去重）
    const dailyActiveUsers = await prisma.messages.findMany({
      where: {
        chat_groups: {
          group_type: 'group' // 只统计群聊，排除私聊
        },
        created_at: {
          gte: todayStart,
          lte: todayEnd
        }
      },
      select: {
        sender_id: true
      },
      distinct: ['sender_id']
    });

    return {
      memberCount: totalUsers,
      dailyActiveUsers: dailyActiveUsers.length
    };
  }

  /**
   * 统计用户在指定时间范围内发送的消息数量
   * @param {number} userId 用户ID
   * @param {Date} startDate 开始时间
   * @param {Date} endDate 结束时间
   * @returns {Promise<number>}
   */
  static async countUserMessagesInRange(userId, startDate, endDate) {
    const total = await prisma.messages.count({
      where: {
        sender_id: BigInt(userId),
        created_at: {
          gte: startDate,
          lte: endDate
        }
      }
    });
    return total;
  }

  /**
   * 获取用户当天已发送的消息数量
   * @param {number} userId 用户ID
   * @param {Date} [date=new Date()] 日期
   * @returns {Promise<number>}
   */
  static async getUserDailyMessageCount(userId, date = new Date()) {
    const { start, end } = getDayRange(date);
    return this.countUserMessagesInRange(userId, start, end);
  }

  /**
   * 获取用户发送的消息统计
   * @param {number} userId 用户ID
   * @returns {Promise<Object>}
   */
  static async getUserMessageStats(userId) {
    const [total, today] = await Promise.all([
      prisma.messages.count({ where: { sender_id: BigInt(userId) } }),
      prisma.messages.count({
        where: {
          sender_id: BigInt(userId),
          created_at: {
            gte: new Date(new Date().setHours(0, 0, 0, 0))
          }
        }
      })
    ]);

    return { total, today };
  }

  /**
   * 批量删除群组消息
   * @param {number} groupId 群组ID
   * @param {Date} beforeDate 删除此日期之前的消息
   * @returns {Promise<number>} 删除的消息数量
   */
  static async deleteGroupMessagesBefore(groupId, beforeDate) {
    const result = await prisma.messages.deleteMany({
      where: {
        group_id: parseInt(groupId),
        created_at: { lt: beforeDate }
      }
    });

    return result.count;
  }

  /**
   * 搜索消息
   * @param {Object} options 搜索选项
   * @returns {Promise<Object>}
   */
  static async searchMessages(options = {}) {
    const { 
      groupId, 
      userId, 
      keyword, 
      messageType, 
      page = 1, 
      pageSize = 20 
    } = options;

    const pageNum = parseInt(page);
    const pageSizeNum = parseInt(pageSize);
    const skip = (pageNum - 1) * pageSizeNum;

    const where = {};

    if (groupId) {
      where.group_id = parseInt(groupId);
    }

    if (userId) {
      where.sender_id = BigInt(userId);
    }

    if (keyword) {
      where.content = { contains: keyword };
    }

    if (messageType) {
      where.message_type = messageType;
    }

    const [total, messages] = await Promise.all([
      prisma.messages.count({ where }),
      prisma.messages.findMany({
        where,
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true
            }
          },
          chat_groups: {
            select: {
              id: true,
              group_name: true
            }
          }
        },
        orderBy: { created_at: 'desc' },
        skip,
        take: pageSizeNum
      })
    ]);

    return {
      data: messages.map(message => new MessagePrisma(message)),
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total,
        totalPages: Math.ceil(total / pageSizeNum)
      }
    };
  }

  /**
   * 批量删除消息（管理员功能）
   * @param {number[]} ids 消息ID数组
   * @returns {Promise<number>} 删除的消息数量
   */
  static async deleteByIds(ids) {
    const bigIntIds = ids.map(id => BigInt(id));
    const result = await prisma.messages.deleteMany({
      where: {
        id: {
          in: bigIntIds
        }
      }
    });
    return result.count;
  }

  /**
   * 获取群聊消息列表（管理员版本，包含更多信息）
   * @param {number} groupId 群聊ID
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getAdminGroupMessages(groupId, options = {}) {
    const {
      page = 1,
      pageSize = 20,
      messageType = null,
      search = null,
      senderId = null
    } = options;

    const pageNum = parseInt(page);
    const pageSizeNum = parseInt(pageSize);
    const skip = (pageNum - 1) * pageSizeNum;

    const where = { group_id: parseInt(groupId) };

    if (messageType) {
      where.message_type = messageType;
    }

    if (search) {
      where.content = { contains: search };
    }

    if (senderId) {
      where.sender_id = BigInt(senderId);
    }

    const [total, messages] = await Promise.all([
      prisma.messages.count({ where }),
      prisma.messages.findMany({
        where,
        include: {
          users: {
            select: {
              id: true,
              nickname: true,
              avatar_url: true,
              phone_number: true
            }
          },
          chat_groups: {
            select: {
              id: true,
              group_name: true
            }
          }
        },
        orderBy: { created_at: 'desc' },
        skip,
        take: pageSizeNum
      })
    ]);

    return {
      data: messages.map(message => new MessagePrisma(message)),
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total,
        totalPages: Math.ceil(total / pageSizeNum)
      }
    };
  }

  /**
   * 获取所有群组的合并消息列表（全国总群功能）
   * @param {Object} options 查询选项
   * @returns {Promise<Object>}
   */
  static async getAllGroupsMessages(options = {}) {
    const { page = 1, pageSize = 50, lastMessageId } = options;
    const pageNum = parseInt(page) || 1;
    const pageSizeNum = parseInt(pageSize) || 50;
    const skip = (pageNum - 1) * pageSizeNum;

    // 构建查询条件：只查询群聊类型的消息，排除私聊
    const where = {
      chat_groups: {
        group_type: 'group'
      }
    };

    // 如果提供了lastMessageId，则获取比它更新的消息
    if (lastMessageId && !isNaN(parseInt(lastMessageId))) {
      where.id = { gt: BigInt(lastMessageId) };
    }

    // 获取消息数据，增加查询数量以便去重
    const messages = await prisma.messages.findMany({
      where,
      include: {
        users: {
          select: {
            id: true,
            nickname: true,
            avatar_url: true
          }
        },
        chat_groups: {
          select: {
            id: true,
            group_name: true
          }
        }
      },
      orderBy: { created_at: 'desc' },
      take: pageSizeNum * 3 // 增加查询数量以便去重后有足够的数据
    });

    // 去重逻辑：对于全国总群广播消息，只保留一条；其他消息正常显示
    const uniqueMessages = [];
    const broadcastMessageMap = new Map();

    for (const message of messages) {
      if (message.broadcast_tag === 'national_broadcast') {
        // 全国总群广播消息：相同用户在相同时间（5秒内）发送的相同内容只保留一条
        const timeWindow = Math.floor(new Date(message.created_at).getTime() / 5000); // 5秒时间窗口
        const key = `${message.sender_id}_${message.content}_${timeWindow}_${message.broadcast_tag}`;

        if (!broadcastMessageMap.has(key)) {
          broadcastMessageMap.set(key, true);
          uniqueMessages.push(message);
        }
      } else {
        // 普通群组消息：直接添加，不去重
        uniqueMessages.push(message);
      }
    }

    // 分页处理去重后的消息
    const paginatedMessages = uniqueMessages.slice(skip, skip + pageSizeNum);

    const messagesWithSender = paginatedMessages.map(message => ({
      id: message.id.toString(),
      group_id: message.group_id.toString(),
      sender_id: message.sender_id.toString(),
      message_type: message.message_type,
      content: message.content,
      broadcast_tag: message.broadcast_tag,
      created_at: message.created_at,
      sender: {
        id: message.users?.id?.toString() || message.sender_id.toString(),
        nickname: message.users?.nickname || '未知用户',
        avatar_url: message.users?.avatar_url
      },
      group: {
        id: message.chat_groups?.id?.toString() || message.group_id.toString(),
        group_name: message.broadcast_tag === 'national_broadcast' ? '全国总群' : (message.chat_groups?.group_name || '未知群组')
      }
    }));

    return {
      data: messagesWithSender,
      pagination: {
        page: pageNum,
        pageSize: pageSizeNum,
        total: uniqueMessages.length,
        totalPages: Math.ceil(uniqueMessages.length / pageSizeNum)
      }
    };
  }

  /**
   * 获取所有群组的最新消息（用于全国总群轮询）
   * @param {number} lastMessageId 最后一条消息ID
   * @returns {Promise<Array>}
   */
  static async getAllGroupsNewMessages(lastMessageId = 0) {
    const messages = await prisma.messages.findMany({
      where: {
        chat_groups: {
          group_type: 'group'
        },
        id: { gt: BigInt(lastMessageId) }
      },
      include: {
        users: {
          select: {
            id: true,
            nickname: true,
            avatar_url: true
          }
        },
        chat_groups: {
          select: {
            id: true,
            group_name: true
          }
        }
      },
      orderBy: { created_at: 'asc' }
    });

    // 去重逻辑：对于全国总群广播消息，只保留一条；其他消息正常显示
    const uniqueMessages = [];
    const broadcastMessageMap = new Map();

    for (const message of messages) {
      if (message.broadcast_tag === 'national_broadcast') {
        // 全国总群广播消息：相同用户在相同时间（5秒内）发送的相同内容只保留一条
        const timeWindow = Math.floor(new Date(message.created_at).getTime() / 5000); // 5秒时间窗口
        const key = `${message.sender_id}_${message.content}_${timeWindow}_${message.broadcast_tag}`;

        if (!broadcastMessageMap.has(key)) {
          broadcastMessageMap.set(key, true);
          uniqueMessages.push(message);
        }
      } else {
        // 普通群组消息：直接添加，不去重
        uniqueMessages.push(message);
      }
    }

    return uniqueMessages.map(message => ({
      id: message.id.toString(),
      group_id: message.group_id.toString(),
      sender_id: message.sender_id.toString(),
      message_type: message.message_type,
      content: message.content,
      broadcast_tag: message.broadcast_tag,
      created_at: message.created_at,
      sender: {
        id: message.users?.id?.toString() || message.sender_id.toString(),
        nickname: message.users?.nickname || '未知用户',
        avatar_url: message.users?.avatar_url
      },
      group: {
        id: message.chat_groups?.id?.toString() || message.group_id.toString(),
        group_name: message.broadcast_tag === 'national_broadcast' ? '全国总群' : (message.chat_groups?.group_name || '未知群组')
      }
    }));
  }

  /**
   * 转换为JSON对象
   * @returns {Object}
   */
  toJSON() {
    const result = {
      id: this.id.toString(),
      group_id: this.group_id.toString(),
      sender_id: this.sender_id.toString(),
      message_type: this.message_type,
      content: this.content,
      broadcast_tag: this.broadcast_tag,
      created_at: this.created_at
    };

    // 添加发送者信息
    if (this.users) {
      result.sender = {
        id: this.users.id.toString(),
        nickname: this.users.nickname || '未知用户',
        avatar_url: this.users.avatar_url,
        phone_number: this.users.phone_number
      };
    }

    // 添加群聊信息
    if (this.chat_groups) {
      result.group = {
        id: this.chat_groups.id,
        group_name: this.chat_groups.group_name
      };
    }

    return result;
  }
}

module.exports = MessagePrisma;
